import struct
import tori.instructions
from tori.akatsak import akatsa

def bitar_hutsa(hamartarra,tamaina=16,gui=False):
    if hamartarra>=2**tamaina:
        akatsa(gui, "zenbaki_handiegia", zenb=hamartarra, tam=tamaina)
        return None
    else:
        return struct.pack('>H',hamartarra)

def biren_osagarria(hamartarra,tamaina=16,gui=False):
    if hamartarra>(2**tamaina/2) or hamartarra<-(2**tamaina/2-1):
        akatsa(gui, "zenbaki_hantxikiegia", zenb=hamartarra, tam=tamaina)
        return None
    else:
        return struct.pack('>h',hamartarra)

def agindua_bitarrera(agindua,gui=False):
    "Agindua emanda bitarrean itzultzen da."
    # Arraroa###########
    if agindua[0]==41:
        return struct.pack('>I',agindua[0]*2**26+int(agindua[1])*2**21+int(agindua[2])*2**10+agindua[3])
    # Arraroa############

    # Lehenengo bi byteak    
    a=agindua[0]*1024
    if tori.instructions.bat_bost(tori.instructions.aginduak[agindua[0]][1]):
        a+=int(agindua[1])*32
        if tori.instructions.bi_bost(tori.instructions.aginduak[agindua[0]][1]):
            a+=int(agindua[2])
    elif tori.instructions.bat_hamar(tori.instructions.aginduak[agindua[0]][1]):
        a+=int(agindua[1])

    # Azken bi byteak
    b=0
    fmt = '>H'
    if not tori.instructions.ez_hamasei(tori.instructions.aginduak[agindua[0]][1]):
        b=int(agindua[-1])
    if tori.instructions.helbidea(tori.instructions.aginduak[agindua[0]][1]):
        fmt+='H'
    else:
        fmt+='h'

    # Bitarreratu
    return struct.pack(fmt,a,b)

def a_bitar_hutsa(hamartarra, tamaina=16,gui=False):
    bitarra = ""
    if hamartarra>=2**tamaina:
        akatsa(gui, "zenbaki_handiegia", zenb=hamartarra, tam=tamaina)
        return None
    while hamartarra:
        bitarra = str(hamartarra%2) + bitarra
        hamartarra /=2
    return bitarra.zfill(tamaina)

def i_bitar_hutsa(s):
    return struct.unpack('>H',s)[0]

def i_biren_osagarria(s):
    return struct.unpack('>h',s)[0]


def a_biren_osagarria(hamartarra,tamaina=16,gui=False):
    bitarra = ""
    if hamartarra>(2**tamaina/2) or hamartarra<-(2**tamaina/2-1):
        akatsa(gui, "zenbaki_hantxikiegia", zenb=hamartarra, tam=tamaina)
        return None
    if hamartarra>=0:
        return a_bitar_hutsa(hamartarra,tamaina)
    else:
        bitarra = a_bitar_hutsa(-1*hamartarra-1,tamaina)
        return "".join([str(abs(int(i)-1)) for i in bitarra]) 

def i_a_biren_osagarria(bitarra):
    if bitarra[0]=='0':
        return int(bitarra[1:],2)
    else:
        a=0
        i=len(bitarra)-1
        while i>=0:
            a+=int(bitarra[i])*2**(len(bitarra)-1-i)
            i-=1
        return a-2**len(bitarra)


def a_agindua_bitarrera(agindua,gui=False):
    a,b=struct.unpack('>2H', agindua_bitarrera(agindua))
    return a_bitar_hutsa(a)+a_bitar_hutsa(b)



